﻿using Nop.Admin.Models.Common;
using Nop.Admin.Models.XJ;
using Nop.Core;
using Nop.Core.Domain.XJ;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Logging;
using Nop.Services.Media;
using Nop.Services.Security;
using Nop.Services.XJ;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Kendoui;
using Nop.Web.Framework.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

namespace Nop.Admin.Controllers
{
	public class EquipmentStockController : BaseAdminController
	{
		#region Fields
		private readonly IPermissionService _permissionService;
		private readonly IPictureService _pictureService;
		private readonly IWorkContext _workContext;
		private readonly IOrganizationService _organizationServce;
		private readonly ICustomerService _customerService;
		private readonly IGenericAttributeService _genericAttributeService;
		private readonly IXJPlaceService _xjPlaceService;
		private readonly IXJEquipmentCategoryService _xJEquipmentCategoryService;
		private readonly IXJEquipmentService _xJEquipmentService;
		private readonly IXJEquipmentStockService _xJEquipmentStockService;
		private readonly IXJEquipmentStockLogService _xJEquipmentStockLogService;
		private readonly IXJEquipmentStockInService _xJEquipmentStockInService;
		private readonly IXJEquipmentStockInDetailService _xJEquipmentStockInDetailService;
		private readonly IXJEquipmentStockOutService _xJEquipmentStockOutService;
		private readonly IXJEquipmentStockOutDetailService _xJEquipmentStockOutDetailService;
		private readonly IXJInspectionService _xJInspectionService;
		private readonly IXJInspectionPlanService _xJInspectionPlanService;
		private readonly IXJMaintenanceService _xJMaintenanceService;
		private readonly IXJMaintenanceCommentService _xJMaintenanceCommentService;
		private readonly ICustomerActivityService _customerActivityService;
		private readonly ILogger _logger;
		#endregion

		#region Constructors
		public EquipmentStockController(IPermissionService permissionService,
			IPictureService pictureService,
			IWorkContext workContext,
			IOrganizationService organizationServce,
			ICustomerService customerService,
			IGenericAttributeService genericAttributeService,
			IXJPlaceService xjPlaceService,
			IXJEquipmentCategoryService xJEquipmentCategoryService,
			IXJEquipmentService xJEquipmentService,
			IXJEquipmentStockService xJEquipmentStockService,
			IXJEquipmentStockLogService xJEquipmentStockLogService,
			IXJEquipmentStockInService xJEquipmentStockInService,
			IXJEquipmentStockInDetailService xJEquipmentStockInDetailService,
			IXJEquipmentStockOutService xJEquipmentStockOutService,
			IXJEquipmentStockOutDetailService xJEquipmentStockOutDetailService,
			IXJInspectionService xJInspectionService,
			IXJInspectionPlanService xJInspectionPlanService,
			IXJMaintenanceService xJMaintenanceService,
			IXJMaintenanceCommentService xJMaintenanceCommentService,
			ICustomerActivityService customerActivityService,
			ILogger logger)
		{
			this._permissionService = permissionService;
			this._pictureService = pictureService;
			this._workContext = workContext;
			this._organizationServce = organizationServce;
			this._customerService = customerService;
			this._genericAttributeService = genericAttributeService;
			this._xjPlaceService = xjPlaceService;
			this._xJEquipmentCategoryService = xJEquipmentCategoryService;
			this._xJEquipmentService = xJEquipmentService;
			this._xJEquipmentStockService = xJEquipmentStockService;
			this._xJEquipmentStockLogService = xJEquipmentStockLogService;
			this._xJEquipmentStockInService = xJEquipmentStockInService;
			this._xJEquipmentStockInDetailService = xJEquipmentStockInDetailService;
			this._xJEquipmentStockOutService = xJEquipmentStockOutService;
			this._xJEquipmentStockOutDetailService = xJEquipmentStockOutDetailService;
			this._xJInspectionService = xJInspectionService;
			this._xJInspectionPlanService = xJInspectionPlanService;
			this._xJMaintenanceService = xJMaintenanceService;
			this._xJMaintenanceCommentService = xJMaintenanceCommentService;
			this._customerActivityService = customerActivityService;
			this._logger = logger;
		}
		#endregion

		#region Untilities

		[NonAction]
		private int GetDays(DateTime? startOn, DateTime? endOn)
		{
			if (startOn.HasValue && endOn.HasValue)
			{
				TimeSpan timeSpan = endOn.Value.Subtract(startOn.Value);
				return (int)Math.Round(timeSpan.TotalDays, 0);
			}
			return 0;
		}

		[NonAction]
		protected virtual void PrepareStocksModel(EquipmentStockModel model)
		{
			if (model == null)
				throw new ArgumentNullException("model");

			var equipment = _xJEquipmentService.GetXJEquipmentById(model.EquipmentId);
			if (equipment != null)
			{
				model.EquipmentId = equipment.Id;
				model.Name = equipment.Name;
				model.Manufacturer = equipment.Manufacturer;
				model.Specification = equipment.Specification;
				model.Price = equipment.Price;
				model.Location = equipment.Name;
				model.Amount = 1;
			}

			model.AvailablePlaces.Add(new SelectListItem
			{
				Text = "请选择",
				Value = "0"
			});
			if (equipment.Places.Any())
			{
				foreach (var p in equipment.Places)
					model.AvailablePlaces.Add(new SelectListItem { Text = p.Name, Value = p.Id.ToString() });
			}
		}
		#endregion

		#region List
		public ActionResult Index()
		{
			return RedirectToAction("List");
		}

		public virtual ActionResult List()
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new EquipmentStockListModel();

			model.AvailableCategories.Add(new SelectMenuModel
			{
				name = "全部",
				id = 0,
				open = true
			});
			var categorys = _xJEquipmentCategoryService.GetAllCategorys(showHidden: false);
			foreach (var c in categorys)
				model.AvailableCategories.Add(new SelectMenuModel { name = c.Name, id = c.Id, pId = c.PId });
			return View(model);
		}

		[HttpPost]
		public virtual ActionResult List(DataSourceRequest command, EquipmentStockListModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedKendoGridJson();

			var stocks = _xJEquipmentStockService.GetAllStocks(
				categoryId: model.SearchCategoryId,
				placeId: model.SearchPlaceId,
				equipmentId: model.SearchEquipmentId,
				name: model.SearchName,
				location: model.SearchLocation,
				state: model.SearchState,
				pageIndex: command.Page - 1,
				pageSize: command.PageSize);
			var gridModel = new DataSourceResult
			{
				Data = stocks.Select(x =>
				{
					x.StateName = Enum.GetName(typeof(StockStateEnum), x.State);
					x.Days = GetDays(x.StartOn, x.EndOn);
					return x;
				}),
				Total = stocks.TotalCount
			};
			return Json(gridModel);
		}
		#endregion

		public virtual ActionResult Popup(string btnId, int eId)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new EquipmentStockListModel
			{
				SearchEquipmentId = eId,
				SearchState = (int)StockStateEnum.正常,
			};
			model.AvailablePlaces.Add(new SelectListItem
			{
				Text = "全部",
				Value = "0"
			});
			var equipment = _xJEquipmentService.GetXJEquipmentById(eId);
			if (equipment != null && equipment.Places.Any())
			{
				foreach (var p in equipment.Places)
					model.AvailablePlaces.Add(new SelectListItem { Text = p.Name, Value = p.Id.ToString() });
			}
			model.AvailableStates.Add(new SelectListItem
			{
				Text = "全部",
				Value = "0"
			});
			Type enumState = typeof(StockStateEnum);
			Enum.GetNames(enumState).ToList().ForEach(s =>
			{
				string value = Enum.Format(enumState, Enum.Parse(enumState, s), "d");
				model.AvailableStates.Add(new SelectListItem { Text = s, Value = value });
			});
			ViewBag.btnId = btnId;
			return View(model);
		}

		public virtual ActionResult AddPopup(int eId)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var customer = _workContext.CurrentCustomer;
			var model = new EquipmentStockModel
			{
				EquipmentId = eId,
				CustomerId = customer.Id,
				CreatedOn = DateTime.Now,
				StartOn = DateTime.Today,
			};
			PrepareStocksModel(model);
			return View(model);
		}

		public virtual ActionResult EditPopup(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var model = new EquipmentStockModel();

			var stock = _xJEquipmentStockService.GetXJEquipmentStockById(id);
			if (null != stock)
			{
				model.Id = stock.Id;
				model.PlaceId = stock.PlaceId;
				model.Location = stock.Location;
				model.EquipmentId = stock.EquipmentId;
				model.Name = stock.Name;
				model.Manufacturer = stock.Manufacturer;
				model.Specification = stock.Specification;
				model.Price = stock.Price;
				model.Amount = stock.Amount;
				model.CustomerId = stock.CustomerId;
				model.CreatedOn = stock.CreatedOn;
				model.StartOn = stock.StartOn;
			}
			PrepareStocksModel(model);
			return View(model);
		}

		[HttpPost]
		[FormValueRequired("save")]
		public virtual ActionResult AddPopup(string btnId, EquipmentStockModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var equipment = _xJEquipmentService.GetXJEquipmentById(model.EquipmentId);
			if (null == equipment)
			{
				ModelState.AddModelError("", "设施设备无效");
			}

			var place = _xjPlaceService.GetXJPlaceById(model.PlaceId);
			if (null == place)
			{
				ModelState.AddModelError("", "请选择巡检点");
			}

			if (ModelState.IsValid)
			{
				if (model.Amount > 1)
				{
					for (int i = 0; i < model.Amount; i++)
					{
						var stock = new XJEquipmentStock
						{
							PlaceId = model.PlaceId,
							Location = string.Format("{0}{1}", model.Location ?? "", i + 1),
							EquipmentId = equipment.Id,
							Name = equipment.Name,
							Manufacturer = equipment.Manufacturer,
							Specification = equipment.Specification,
							Price = model.Price,
							Amount = 1,
							CustomerId = _workContext.CurrentCustomer.Id,
							CreatedOn = DateTime.Now,
							StartOn = model.StartOn,
							State = (int)StockStateEnum.正常
						};
						_xJEquipmentStockService.InsertXJEquipmentStock(stock);
					}
				}
				else
				{
					var stock = new XJEquipmentStock
					{
						PlaceId = model.PlaceId,
						Location = model.Location,
						EquipmentId = equipment.Id,
						Name = equipment.Name,
						Manufacturer = equipment.Manufacturer,
						Specification = equipment.Specification,
						Price = model.Price,
						Amount = 1,
						CustomerId = _workContext.CurrentCustomer.Id,
						CreatedOn = DateTime.Now,
						StartOn = model.StartOn,
						State = (int)StockStateEnum.正常
					};
					_xJEquipmentStockService.InsertXJEquipmentStock(stock);
				}

				// 更新平均使用时间
				_xJEquipmentService.UpdateMeanLife(model.EquipmentId);
				// 更新使用中数量
				_xJEquipmentService.UpdateUseIn(model.EquipmentId);

				ViewBag.RefreshPage = true;
				ViewBag.btnId = btnId;
			}
			PrepareStocksModel(model);
			return View(model);
		}

		[HttpPost]
		[FormValueRequired("save")]
		public virtual ActionResult EditPopup(string btnId, string formId, EquipmentStockModel model)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			if (ModelState.IsValid)
			{
				var stock = _xJEquipmentStockService.GetXJEquipmentStockById(model.Id);
				if (null != stock)
				{
					stock.PlaceId = model.PlaceId;
					stock.Location = model.Location;
					stock.StartOn = model.StartOn;
					_xJEquipmentStockService.UpdateXJEquipmentStock(stock);

					ViewBag.RefreshPage = true;
					ViewBag.btnId = btnId;
				}
			}

			//categories
			PrepareStocksModel(model);
			return View(model);
		}

		/// <summary>
		/// 停止使用
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public virtual ActionResult StockStop(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var stock = _xJEquipmentStockService.GetXJEquipmentStockById(id);
			if (null != stock)
			{
				stock.EndOn = DateTime.Today;
				stock.State = (int)StockStateEnum.报废;
				_xJEquipmentStockService.UpdateXJEquipmentStock(stock);
				// 更新平均使用时间
				_xJEquipmentService.UpdateMeanLife(stock.EquipmentId);
				// 更新使用中数量
				_xJEquipmentService.UpdateUseIn(stock.EquipmentId);
			}

			return new NullJsonResult();
		}

		/// <summary>
		/// 恢复使用
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		[HttpPost]
		public virtual ActionResult StockStart(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var stock = _xJEquipmentStockService.GetXJEquipmentStockById(id);
			if (null != stock)
			{
				stock.EndOn = null;
				stock.State = (int)StockStateEnum.正常;
				_xJEquipmentStockService.UpdateXJEquipmentStock(stock);
				// 更新平均使用时间
				_xJEquipmentService.UpdateMeanLife(stock.EquipmentId);
				// 更新使用中数量
				_xJEquipmentService.UpdateUseIn(stock.EquipmentId);
			}

			return new NullJsonResult();
		}
		[HttpPost]
		public virtual ActionResult StockGenerate(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			int customerId = _workContext.CurrentCustomer.Id;
			DateTime nowTime = DateTime.Today;
			var equipment = _xJEquipmentService.GetXJEquipmentById(id);
			if (null != equipment)
			{
				if (equipment.Places != null && equipment.Places.Any())
				{
					foreach (var p in equipment.Places)
					{
						var stock = new XJEquipmentStock
						{
							PlaceId = p.Id,
							Location = p.Location,
							EquipmentId = equipment.Id,
							Name = equipment.Name,
							Manufacturer = equipment.Manufacturer,
							Specification = equipment.Specification,
							Price = equipment.Price,
							Amount = 1,
							CustomerId = customerId,
							CreatedOn = nowTime,
							StartOn = nowTime,
							State = (int)StockStateEnum.正常
						};
						_xJEquipmentStockService.InsertXJEquipmentStock(stock);
					}
				}
				// 更新使用中数量
				_xJEquipmentService.UpdateUseIn(equipment.Id);
			}

			return new NullJsonResult();
		}

		[HttpPost]
		public virtual ActionResult Delete(int id)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			var stock = _xJEquipmentStockService.GetXJEquipmentStockById(id);
			if (stock == null)
				return Json(new { result = false, msg = "不能删除" });

			try
			{
				_xJEquipmentStockService.DeleteXJEquipmentStock(stock);

				// 更新平均使用时间
				_xJEquipmentService.UpdateMeanLife(stock.EquipmentId);
				// 更新使用中数量
				_xJEquipmentService.UpdateUseIn(stock.EquipmentId);

				//activity log
				_customerActivityService.InsertActivity("DeleteEquipmentStock", "删除使用明细：{0}", stock.Id);

				return Json(new { result = true, msg = "删除成功" });
			}
			catch (Exception ex)
			{
				return Json(new { result = false, msg = ex.Message });
			}
			//return new NullJsonResult();
		}


		[HttpPost]
		public virtual ActionResult DeleteSelected(ICollection<int> selectedIds)
		{
			if (!_permissionService.Authorize(StandardPermissionProvider.ManageEquipments))
				return AccessDeniedView();

			try
			{
				if (selectedIds != null)
				{
					var stocks = _xJEquipmentStockService.GetStocksByIds(selectedIds.ToArray());
					if (stocks.Any())
					{
						foreach (var stock in stocks)
						{
							_xJEquipmentStockService.DeleteXJEquipmentStock(stock);

							// 更新平均使用时间
							_xJEquipmentService.UpdateMeanLife(stock.EquipmentId);
							// 更新使用中数量
							_xJEquipmentService.UpdateUseIn(stock.EquipmentId);

							//activity log
							_customerActivityService.InsertActivity("DeleteEquipmentStock", "删除使用明细：{0}", stock.Id);
						}
						return Json(new { Result = true });
					}
					else
					{
						return Json(new { Result = false, Msg = "未选中删除行" });
					}
				}
				return Json(new { Result = false, Msg = "未选中删除行" });
			}
			catch (Exception ex)
			{
				return Json(new { Result = false, Msg = ex.Message });
			}
		}
	}
}